/**
 * Pagination.java 1.0 2007-5-7 下午09:45:16,创建 by yangfan
 */


package org.in4j.core.dao.support;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 *
 * @author yangfan
 * @version 1.0 2007-5-7 下午09:45:16,创建
 */
public class Pagination<T>
{
	public final static int PAGESIZE = 25;

	public final static int PAGE_NO_FIRST = 1;

	private int pageSize = PAGESIZE;

	private List<T> items;

	private int recordCount;

	private int[] pages = new int[0];

	private int pageNo;

	private int previousPage;

	private int nextPage;

	private int pageCount;

	private int startIndex;

	private int endIndex;

	public Pagination(List<T> items, int recordCount)
	{
		this(items, recordCount, PAGE_NO_FIRST);
	}

	public Pagination(List<T> items, int recordCount, int pageNo)
	{
		this(items, recordCount, pageNo, PAGESIZE);
	}

	public Pagination(List<T> items, int recordCount, int pageNo, int pageSize)
	{
		this.items = items;
		this.recordCount = recordCount;
		this.pageSize = pageSize;
		this.pageNo = pageNo;
		compute();
	}

	private void compute()
	{
		if(items != null && this.recordCount < items.size())
			throw new IllegalArgumentException("记录总数小于查询结果总数.");
		if(this.recordCount <= 0)
		{
			this.pageCount = 0;
			this.pageNo = 1;
			this.previousPage = 1;
			this.nextPage = 1;
			this.startIndex = 0;
			this.endIndex = 0;
		}
		else
		{
			pageCount = recordCount / pageSize;
			if(recordCount % pageSize > 0)
				pageCount++;
			this.pageNo = checkPageNoRange(pageNo,PAGE_NO_FIRST,pageCount);

			this.previousPage = pageNo - 1;
			this.previousPage = checkPageNoRange(previousPage,PAGE_NO_FIRST,pageCount);

			this.nextPage = pageNo + 1;
			this.nextPage = checkPageNoRange(nextPage,PAGE_NO_FIRST,pageCount);

			pages = new int[pageCount];
			for(int i = 0; i < pageCount; i++)
			{
				pages[i] = i + 1;
			}
			this.startIndex = (pageNo - 1) * pageSize;
			if(items != null && items.size() < pageSize)
			{
				this.endIndex = (pageNo - 1) * pageSize + items.size();
			}
			else
			{
				this.endIndex = pageNo * pageSize;
			}
		}
	}

	public void setItems(List<T> items)
	{
		this.items = items;
		compute();
	}

	public List<T> getItems()
	{
		return items;
	}

	public int getPageNo()
	{
		return pageNo;
	}

	public int getNextPage()
	{
		return nextPage;
	}

	public int getPreviousPage()
	{
		return previousPage;
	}

	public boolean hasPreviousPage()
	{
		return this.previousPage < this.pageNo;
	}

	public boolean hasNextPage()
	{
		return this.previousPage > this.pageNo;
	}

	public int[] getPages()
	{
		return pages;
	}

	public int[] getNearestPages(int distance)
	{
		return getNearestPages(distance,distance);
	}

	public int[] getNearestPages(int beforeDistance,int afterDistance)
	{
		int startPage = pageNo - beforeDistance;
		int endPage = pageNo + afterDistance;
		startPage = checkPageNoRange(startPage,PAGE_NO_FIRST,pageCount);
		endPage = checkPageNoRange(endPage,PAGE_NO_FIRST,pageCount);
		final int count = endPage + 1 - startPage;
		int[] pages = new int[count];
		for(int i = 0; i < count; i++)
		{
			pages[i] = i + startPage;
		}
		return pages;
	}

	public int getPageSize()
	{
		return pageSize;
	}

	public int getRecordCount()
	{
		return recordCount;
	}

	public int getPageCount()
	{
		return pageCount;
	}

	public int getStartIndex()
	{
		return this.startIndex;
	}

	public int getEndIndex()
	{
		return this.endIndex;
	}

	private int checkPageNoRange(int pageNo,int floor,int celing)
	{
		int result = pageNo;
		if(result < floor) result = floor;
		if(result > celing) result = celing;
		return result;
	}

	public static void main(String[] args)
	{
		List<String> items = new ArrayList<String>();
		for(int i = 0; i < 5; i++)
		{
			items.add("test" + i);
		}
		Pagination<String> pager = new Pagination<String>(items,33,4,5);
		System.out.println(pager.getPreviousPage());
		System.out.println(pager.getNextPage());
		int[] pages = pager.getNearestPages(1,2);
		System.out.println(Arrays.toString(pages));
		System.out.println(Arrays.toString(pager.getPages()));
	}
}
